package com.alphaking.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.alphaking.pojo.common.KeyAndValue;
import com.alphaking.pojo.common.PagerResult;
import com.alphaking.pojo.common.SearchBean;
import com.alphaking.pojo.common.SearchCondition;
import com.alphaking.util.DataConvertorUtil;

public class BaseDaoImpl<T> {
	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	protected Class<T> clazz;

	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	public BaseDaoImpl() {
		ParameterizedType type = (ParameterizedType) this.getClass()
				.getGenericSuperclass();
		this.clazz = (Class) type.getActualTypeArguments()[0];
		System.out.println("BasicDao ----- clazz = " + this.clazz);
	}

	/**
	 * 保存记录
	 */
	public T save(T entity) {
		T proxyEntity =  (T)getSession().save(entity);
		getSession().flush();
		return proxyEntity;
	}

	/**
	 *更新记录
	 */
	public void update(T entity) {
		getSession().update(entity);
		getSession().flush();
	}
	
	
	/**
     * 保存或者更新记录
     * @param entity
    */
	public void saveOrUpdate(T entity){
		getSession().saveOrUpdate(entity);
		getSession().flush();
	}
	
	
	/**
	 * 通过sql更新记录
	 */
	public Integer updateBySql(String sql) {
		Query query = getSession().createSQLQuery(sql);
		return query.executeUpdate();
	}
	
	/**
	 * 通过hql更新记录
	 */
	public Integer updateByHql(String hql){
		
		Integer result = getSession().createQuery(hql).executeUpdate();		
		return result;
	}

	/**
	 * 通过hql更新记录
	 */
	public Integer updateByHql(String hql, Object...params){
		
		Query query = getSession().createQuery(hql);
	    for (int i = 0; i < params.length; i++) {
			query.setParameter(i, params[i]);
		}
	    return query.executeUpdate();
	}
	
	/**
	 *通过id删除记录
	 */
	public void delete(Serializable id) {
		Object obj = getById(id);
		if (obj != null) {
			getSession().delete(obj);
		}
		getSession().flush();
	}
	
	/**
	 * 删除符合条件的记录
	 */
	public void deleteAll(SearchCondition searchCondition) throws NoSuchFieldException, SecurityException{
		System.out.println(searchCondition);
		searchCondition = SearchCondition.initSearchCondition(searchCondition);
		System.out.println(searchCondition);
		
		String hql = SearchCondition.getHql(clazz, searchCondition);
		String[] tempHQL = hql.split(" order by");
		hql = "delete " + tempHQL[0];
		Query query = getQuery(hql, searchCondition);
		query.executeUpdate();
	}
	
	/**
	 *通过id找记录
	 */
	public T getById(Serializable id) {
		return (T) getSession().get(clazz, id);
	}

	
	public Number getSum(String key,SearchCondition searchCondition) throws NoSuchFieldException, SecurityException{
		System.out.println(searchCondition);
		searchCondition = SearchCondition.initSearchCondition(searchCondition);
		System.out.println(searchCondition);
		
		String hql = SearchCondition.getHql(clazz, searchCondition);
		String[] tempHQL = hql.split(" order by");
		hql = "select sum("+key+") " + tempHQL[0];
		Query query = getQuery(hql, searchCondition);
		List<Object> list = query.list();
		if(list!=null && list.size()>0&& list.get(0)!=null ){
			return (Number)list.get(0);
		}
		String fieldDataType = DataConvertorUtil.getFieldDataTypeByName(clazz,key);
		Object sum = DataConvertorUtil.unknowDataType2Object(fieldDataType, "0");
		return (Number)sum;
	}
	
	
	/**
	 * 创建查询语句并赋值
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public Query getQuery(String hql,SearchCondition searchCondition) throws NoSuchFieldException, SecurityException{
		List<SearchBean> searchBeans = searchCondition.getSearchBeans();
		
		Query query = getSession().createQuery(hql);
		int k = 0;
		
		for(SearchBean searchBean : searchBeans){
			if(searchBean!=null && searchBean.getOperator()!=null && !searchBean.getOperator().equals("") && searchBean.getKey()!=null && !searchBean.getKey().equals("") && searchBean.getValue()!=null && !searchBean.getValue().equals("")){
				String operator = searchBean.getOperator();
				String key = searchBean.getKey();
				String value = searchBean.getValue();
				String fieldDataType = DataConvertorUtil.getFieldDataTypeByName(clazz,key);
				Object parameter = "";
				
				switch(operator){
				case SearchBean.OPERATOR_IN :
					String[] splitArray = value.split("-~-~-");
					for(String str : splitArray){
						parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, str);
						query.setParameter(k++, parameter);
					}
					break;
				case SearchBean.OPERATOR_LIKE :
					query.setParameter(k++, "%"+value+"%");
					break;
				case SearchBean.OPERATOR_EQ :
					parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, value);
					query.setParameter(k++, parameter);
					break;
				case SearchBean.OPERATOR_NE :
					parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, value);
					query.setParameter(k++, parameter);
					break;
				case SearchBean.OPERATOR_LT :
					parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, value);
					query.setParameter(k++, parameter);
					break;
				case SearchBean.OPERATOR_GT :
					parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, value);
					query.setParameter(k++, parameter);
					break;
				case SearchBean.OPERATOR_LE :
					parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, value);
					query.setParameter(k++, parameter);
					break;
				case SearchBean.OPERATOR_GE :
					parameter = DataConvertorUtil.unknowDataType2Object(fieldDataType, value);
					query.setParameter(k++, parameter);
					break;
				default :
					break;
				}
			}
		}
		
		return query;
	}
	
	/**
	 *统计查询总数
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public Long getCount(SearchCondition searchCondition) throws NoSuchFieldException, SecurityException {
		System.out.println(searchCondition);
		searchCondition = SearchCondition.initSearchCondition(searchCondition);
		System.out.println(searchCondition);
		
		String hql = SearchCondition.getHql(clazz, searchCondition);
		String[] tempHQL = hql.split(" order by");
		hql = "select count(*) " + tempHQL[0];
		Query query = getQuery(hql, searchCondition);
		List<Object> list = query.list();
		if(list!=null && list.size()>0 && list.get(0)!=null){
			return ((Number)list.get(0)).longValue();
		}
		return new Long(0);
	}
	
	
	/**
	 *获取查询的唯一值
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public T getUniqueResult(SearchCondition searchCondition) throws NoSuchFieldException, SecurityException{
		System.out.println(searchCondition);
		searchCondition = SearchCondition.initSearchCondition(searchCondition);
		System.out.println(searchCondition);
		
		String hql = SearchCondition.getHql(clazz,searchCondition);
		Query query = getQuery(hql, searchCondition);
		return (T)query.uniqueResult();
	}
	
	/**
	 * （分页）查询列表
	 * @param isPager
	 * @param searchCondition
	 * @return
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public  PagerResult<T> listModel(boolean isPager,SearchCondition searchCondition) throws NoSuchFieldException, SecurityException{
		System.out.println("--------listModel--------");
		System.out.println(searchCondition);
		searchCondition = SearchCondition.initSearchCondition(searchCondition);
		System.out.println(searchCondition);
		
		String hql = SearchCondition.getHql(clazz,searchCondition);
		Query query = getQuery(hql, searchCondition);
		
		List<T> resultSet;
		if(isPager){
			resultSet = query.setFirstResult((searchCondition.getPageNum()-1)*searchCondition.getSize()).setMaxResults(searchCondition.getSize()).list();
		}else{
			resultSet = query.list();
		}
		
		Long count = getCount(searchCondition);
		
		PagerResult<T> pagerResult = new PagerResult<T>();
		pagerResult.setResultSet(resultSet);
		pagerResult.setCount(count);
		
		if(resultSet==null || resultSet.size()==0){
			return pagerResult;
		}
		
		if(isPager){
			Long firstPage = new Long(1);
			Long currentPage = new Long(searchCondition.getPageNum());
			Long lastPage = count/searchCondition.getSize();
			Long totalPage = count/searchCondition.getSize();
			
			if(count%searchCondition.getSize()!=0){
				lastPage = count/searchCondition.getSize() + 1;
				totalPage = count/searchCondition.getSize() + 1;
			}
			
			Long previousPage = firstPage;
			Long nextPage = lastPage;
			
			if(firstPage<currentPage){
				previousPage = currentPage - 1;
			}
			
			if(lastPage>currentPage){
				nextPage = currentPage + 1;
			}
			
			List<Long> pageList = new ArrayList<Long>();
			for(int i=0;i<totalPage;i++){
				pageList.add(new Long(i+1));
			}
			
			pagerResult.setFirstPage(firstPage);
			pagerResult.setPreviousPage(previousPage);
			pagerResult.setCurrentPage(currentPage);
			pagerResult.setNextPage(nextPage);
			pagerResult.setLastPage(lastPage);
			pagerResult.setTotalPage(totalPage);
			pagerResult.setPageList(pageList);
			
		}
		
		return pagerResult;
	}
	
}
